﻿#include "searchlistwidget.h"
#include "ui_searchlistwidget.h"
#include <QTimer>
#include "songmanager.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDebug>
#include <QUrl>
SearchListWidget::SearchListWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SearchListWidget)
{
    ui->setupUi(this);
    initUI();
    qDebug() << "SearchListWidget()";
}

SearchListWidget::~SearchListWidget()
{
    qDebug() << "~SearchListWidget()";
    delete ui;
}

#include <QResizeEvent>
// 添加事件过滤器函数以处理大小变化
bool SearchListWidget::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui->scrollArea->viewport() && event->type() == QEvent::Resize) {
        // 当窗口大小变化时调整container的最小宽度
        QResizeEvent *resizeEvent = (QResizeEvent*)(event);
        int newWidth = resizeEvent->size().width();
        ui->container->setMinimumWidth(newWidth);
    } else if (watched == ui->SearchListWidgetStyle && event->type() == QEvent::Resize) {
        int width = ui->SearchListWidgetStyle->width();
        ui->widget_head->setMaximumWidth(width - 87);
    }

    return QWidget::eventFilter(watched, event);
}

void SearchListWidget::addSongItem(SongItemWidget *songItem)
{
    songItem->setImageSize(70);
    _songItems.push_back(songItem);
    songItem->setIndex(_songItems.size());
    connect(songItem, &SongItemWidget::played, this, &SearchListWidget::on_songItem_played);
    ui->container->layout()->addWidget(songItem);
}

void SearchListWidget::search(const QString& searchText)
{
    if(searchText == _cur_search_text) return; // 避免重复搜索
    _search_id++;
    _cur_search_text = searchText;

    // 清除上次的搜索记录, 也即每次都搜一次
    clearOldDatas();

    SearchManager::getInstance().searchSongs(
        searchText,
        std::bind(&SearchListWidget::on_songsReply_finished, this, _search_id, std::placeholders::_1)
    );
}

void SearchListWidget::initUI()
{
    QVBoxLayout *containerLayout = static_cast<QVBoxLayout*>(ui->container->layout());
    containerLayout->setAlignment(Qt::AlignTop);       // 布局内所有子控件顶对齐
    containerLayout->setContentsMargins(60, 0, 57, 0);    // 左边距60, 右边距 60-3

    // ban掉可能出现的横向滑动条
    ui->scrollArea->setWidgetResizable(true);
    ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 永久关掉横向
    ui->scrollArea->viewport()->installEventFilter(this); // 添加事件过滤器来处理滚动区域大小变化
    ui->SearchListWidgetStyle->installEventFilter(this);
}

void SearchListWidget::clearOldDatas()
{
    auto s = _songItems; _songItems.clear();
    for(int i = 0; i < s.size(); i++){
        ui->container->layout()->removeWidget(s[i]);
        s[i]->deleteLater();
    }
    _id.clear();
}

void SearchListWidget::updateSearchText()
{
    QString htmlText = "<span style='font-family:Microsoft YaHei; font-size:33px; font-weight:bold; color:#202020;'>" + _cur_search_text + "</span>   "
                       "<span style='font-family:Microsoft YaHei; font-size:20px; color:#9ca3af;'>的相关搜索如下，找到" + QString::number(_songItems.size()) +"首单曲</span>";
    ui->label_searchText->setText(htmlText);
    ui->label_searchText->setTextFormat(Qt::RichText);  // 确保是富文本模式
}

void SearchListWidget::getPicUrlByAlbumId(int index, qint64 album_id)
{
    SearchManager::getInstance().searchAlbum(
        album_id,
        std::bind(&SearchListWidget::on_albumReply_finished, this, _search_id, index, std::placeholders::_1)
    );
}

void SearchListWidget::getSongUrl(SongItemWidget *songItem, qint64 song_id)
{
    songItem->songItem().wangyiyun_id = song_id;
    QString song_url = "http://music.163.com/song/media/outer/url?id=" + QString::number(song_id) + ".mp3";
    if(SongManager::instance()->exist(song_url))
    {
        songItem->setUrl(song_url);
        songItem->connectManager();
        songItem->setImage(songItem->songItem().image); // 这里得手动设置一下
        return;
    }
    SearchManager::getInstance().checkUrl(
        song_url,
        std::bind(&SearchListWidget::on_checkUrl_finished, this, _search_id, songItem, song_url, std::placeholders::_1)
    );
}

void SearchListWidget::on_checkUrl_finished(int search_id, SongItemWidget *songItem, const QString& song_url, QByteArray data)
{
    if(search_id != _search_id)
    {
        qDebug() << search_id << " 的搜索结果忽略, 当前搜索 : " << _search_id;
        return;
    }
    if(data.size()) songItem->setUrl(song_url);
    else
    {
        qDebug() << "song_url : " << song_url << " 无效";
        songItem->setDuration(0);
    }
}


void SearchListWidget::on_songsReply_finished(int search_id, QByteArray data)
{
    if(search_id != _search_id)
    {
        qDebug() << search_id << " 的搜索结果忽略, 当前搜索 : " << _search_id;
        return;
    }

    QJsonDocument doc = QJsonDocument::fromJson(data);
    QJsonObject root = doc.object();
    QJsonObject result = root.value("result").toObject();
    QJsonArray songs = result.value("songs").toArray();

    const int size = songs.size();
    for(int i = 0; i < size; i++) addSongItem(new SongItemWidget(this));
    for(auto& e : _songItems) e->show(); // 不加这句,加载时会卡成一坨...原因未知

    updateSearchText();
    _id.resize(size);
    for(int i = 0; i < size; i++) _id[i] = 0;
    for(int i = 0; i < size; i++){
        QJsonObject song = songs[i].toObject();
        // 1. 名字
        QString name = song.value("name").toString(); // 名字
        _songItems[i]->setName(name);
        // 2. 歌手, 这是个[]
        QString str_artist; // 注:网易云音乐的歌手是个button组,这里简化为一个button,且点击无反应
        QJsonArray artists = song.value("artists").toArray();
        for(int i = 0; i < artists.size(); i++){
            QJsonObject artist = artists[i].toObject();
            if(str_artist.size()) str_artist += " / ";
            str_artist += artist.value("name").toString();
        }
        _songItems[i]->setArtist(str_artist);
        // 3. 专辑
        QJsonObject album = song.value("album").toObject();
        QString str_album = album.value("name").toString();
        _songItems[i]->setAlbum(str_album);
        // 4. 时长
        int duration = song.value("duration").toInt();
        _songItems[i]->setDuration(duration);
        // 5. id,这个是播放的关键,我们要用id拼接出url
        _id[i] = song.value("id").toVariant().toLongLong(); // 嘛,不过这里获取的id极为有限,vip歌曲的id是一定没有的
                                                            // 补,这里必须用longlong,用int会炸,比如Dye the sky的id是2657747230
        if(_id[i]) getSongUrl(_songItems[i], _id[i]);
        else _songItems[i]->setDuration(0); // 无 id -> 无法播放 -> 时长设置为 0
        // 6. 图片
        int albumId = song.value("album").toObject().value("id").toInt();
        getPicUrlByAlbumId(i, albumId);
    }
}

void SearchListWidget::on_imageReply_finished(int search_id, int index, QByteArray data)
{
    if(search_id != _search_id)
    {
        qDebug() << search_id << " 的搜索结果忽略, 当前搜索 : " << _search_id;
        return;
    }
    QPixmap pixmap;
    pixmap.loadFromData(data);
    _songItems[index]->setImage(pixmap);
    // _songItems[index]->connectManager(); // 这里不能connect,不然每搜一次就要添加很多图片进内存
    // 可以留到播放的时候再connectManager
}

void SearchListWidget::on_albumReply_finished(int search_id, int index, QByteArray data)
{
    if(search_id != _search_id)
    {
        qDebug() << search_id << " 的搜索结果忽略, 当前搜索 : " << _search_id;
        return;
    }
    QJsonDocument albumDoc = QJsonDocument::fromJson(data);
    QJsonObject albumRoot = albumDoc.object();
    QString picUrl = albumRoot.value("album").toObject().value("picUrl").toString();
    // 获取到了url,可以再次发起请求,这次返回的数据就是我们要的图片了
    SearchManager::getInstance().searchImage(
        picUrl,
        std::bind(&SearchListWidget::on_imageReply_finished, this, _search_id, index, std::placeholders::_1)
    );
}

void SearchListWidget::on_songItem_played(int index, bool play)
{
    qDebug() << index;
    emit played(_songItems[index]->songItem(), play);
}

void SearchListWidget::on_pushButton_playAll_clicked()
{
    QVector<QUrl> songs;
    for(auto& e : _songItems)
    {
        if (e->songItem().duration == 0)
            continue;
        if (e->isConnected() == false)
            e->connectManager();
        songs.push_back(e->songItem().url());
    }
    emit playAll(songs);
}
